var REQUESTS   = new Array();
var POSITION   = new Array();
var LOGGING    = new Array();
var CANCEL     = false;
var PAUSE      = false;

$(document).ready(function(){

   resetPosition('noCmd');

   $( "#tabs" ).tabs();

   // Display Ajax Error
   $(document).ajaxError(function(event, request, settings){
         var errorMessage = request.responseText;
         if(errorMessage){
            resetPosition();
            if(errorMessage.match('refused'))
               return;
            if(errorMessage)
               alert(errorMessage, 'Error');
         }
   });


   $.ajaxSetup({
      async: true
   });

   // Make jquery Buttons
   $( "input[type=submit], a, button, #pause_toogle" ).button()
   $( 'input[type=checkbox]' ).button();
       
   // Connect USB Device
   $('#connect_button').click(function() {
      var device = $('#device_select').val();
      var baudrate = $('#baud_select').val();
      $.getJSON("/grbl/connect/"+device+"/"+baudrate, function(data) {
         toConsole(data.result);
      });
   });   

   // Close USB Device
   $('#close_button').click(function() {
      $.getJSON("/grbl/close", function(data) {
         toConsole(['Port closed!']);
      });
   });   

   // Input Command
   $('#command_input').keypress(function (e) {
      if (e.which == 13) {
         var cmd = $('#command_input').val();
         $('#command_input').val('');
         sendCommand(cmd);
      }
   });   

   // Cancel 
   $('#cancel_button').click(function (e) {
      CANCEL = true;
   });   

   // Cancel 
   $('#pause_toogle').change(function (e) {
      if($('#pause_toogle').attr('checked')){
         sendCommand('!');
      } else {
         sendCommand('~');
      }
   });   

   // Check if Serial Port connected 
   $.getJSON("/grbl/connected", function(data) {
      if(data.result == 0){
         toConsole(['Device not connected!'], '', 'red');
         $('#connect_button').trigger('click');
      } 
      else {
         toConsole(['Device is connected!'], '', 'green');
      }
   });

   // Send File to device
   $('#send_button').click(function() {
      var file = $('#gcode_file_select').val() 

      toConsole(['Send file: ' + file + '...'], '', 'green');
      sendCommandsFromFile(file);
   });   


   // Connect USB Device
   $('.move_buttons').click(function() {
      var dir = $(this).attr('dir').split('');
      var step = $("#step_size").val();

      POSITION[dir[0]] += eval( dir[1]+step );

      var cmd = 'G0 ' 
         + 'X' + POSITION['X'].toFixed(3) + ' '
         + 'Y' + POSITION['Y'].toFixed(3) + ' '
         + 'Z' + POSITION['Z'].toFixed(3);

      sendCommand( cmd );
   });   

   // Send File to device
   $('#reset_zero').click(function() {
      resetPosition();
      toConsole(['Reset Coordinates to null ... '], '', 'blue');
   });   



   $("#step_size").spinner({
      min: 0,
      max: 100,
      step: 0.1,
      start: 1000,
      numberFormat: "C",
      culture: 'de-DE'
   });
});

function sendCommandsFromFile(gcodefile) {
   var commands = '';

   delete REQUESTS;

   // Ok, get input from file ...
   $.getJSON("/getFile/" + gcodefile.replace(/\./g, '__'), function(commands) {
      toConsole(['File loaded with ' + commands.length + ' rows.']);


      // now we have a list with commands
      // Problem, we must call this cmd's 
      // in a pseudo synchrounos order!

      // Get Every command and send this to device
      $.each(commands, function(i, cmd) {
         sendCommand( cmd );   
      });

      toConsole(['End of NC File!']);
   });

}

// Send Data to Console
function toConsole(data, addText, color){
console.log(REQUESTS);
   if(typeof(color) == 'undefined')
      color = 'black';

   $.each(data, function(i, entry) {

      // error in text?
      if(entry.match(/^error/i))
         color = 'red';

      // error in text?
      if(typeof(addText) != 'undefined' && addText.match(/^\(/i)){
         LOGGING['LASTCOMMENT'] = addText;
         color = 'gray';
      }

      var txt = '<span style="color:'+ color +'">'
      if(typeof(addText) != 'undefined' && addText){
         txt += addText + ':&nbsp;';
      }
      txt += entry + '</span><br>';
      $(txt).appendTo("#logging");

      $("#logging").scrollTop(10000000000000000);
   });
}

// Send Command to device
function sendCommand(cmd){
   setTimeout(function(){
      if(cmd.match(/^\(/)){ // Comment
         toConsole([cmd]);
      } else {
         var tempcmd = cmd.replace(/[\.|\/]/g, '__');
         REQUESTS[tempcmd] = $.ajax({
            url: "/grbl/command/" + tempcmd,
            dataType: 'json',
            async: false,
            success: function(data) {
               toConsole(data.result, cmd, 'blue');
               refreshDisplay();
            }
         });
      }
   },300);
}

// Reset Position Stack
function resetPosition(noCmd){
   if(! noCmd)
      sendCommand('G92 X0 Y0 Z0');
   
   POSITION['X'] = 0; 
   POSITION['Y'] = 0; 
   POSITION['Z'] = 0; 

   refreshDisplay();
}

// Refresh Display 
function refreshDisplay(){

   REQUESTS['info'] = $.ajax({
      url: "/grbl/info",
      dataType: 'json',
      async: false,
      success: function(data) {
        if(typeof(data.result.state) == 'undefined')
          return;

        // state
        $('#state').text(data.result.state);
   
        // Coordinates
        if(data.result.workpos[0] != null){
          $('#X_wposition').text('X: ' + data.result.workpos[0]);
          $('#Y_wposition').text('Y: ' + data.result.workpos[1]);
          $('#Z_wposition').text('Z: ' + data.result.workpos[2]);
        }
   
        if(data.result.machinepos[0] != null){
          $('#X_mposition').text('X: ' + data.result.machinepos[0]);
          $('#Y_mposition').text('Y: ' + data.result.machinepos[1]);
          $('#Z_mposition').text('Z: ' + data.result.machinepos[2]);
        }

        // last comment
        $('#lastcomment').text(LOGGING['LASTCOMMENT']);
      }
   });
}

